//////////////////////////////////////////////////////////////////////////
// $Id: Constant.cpp,v 1.2 2009/04/06 14:38:03 sunjun Exp $
//////////////////////////////////////////////////////////////////////////

#include "Local.h"

//////////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////////

NAMESPACE_BEGIN

//////////////////////////////////////////////////////////////////////////
	
	Constant::Constant() 
	{
		mType = CT_NONE;
		mData = NULL;
		mCount = 0;
	}

	Constant::~Constant() 
	{
		if(mData){ MDELETE([]mData), mData = NULL; }
	}

	//////////////////////////////////////////////////////////////////////////

	/*
	====================
	setValue
	====================
	*/
	INLINE VOID Constant::setValue( const VOID* data, U32 size )
	{
		CHECK(data);
		if( mType == CT_NONE ) mType = CT_VALUE;
		CHECK( mType == CT_VALUE );
		if( mCount != size )
		{
			if(mData){ MDELETE([]mData), mData = NULL; }
			mData = MNEW(U8[size]); CHECK(mData);
			mCount = size;
		}
		::memcpy(mData,data,size);
	}

	/*
	====================
	setBool
	====================
	*/
	INLINE VOID Constant::setBool( BOOL b )
	{
		if( mType == CT_NONE ) mType = CT_BOOL;
		CHECK( mType == CT_BOOL );
		if(mCount != 1)
		{
			if(mData){ MDELETE([]mData), mData = NULL; }
			mData = MNEW(U8[sizeof(BOOL)]); CHECK(mData);
			mCount = 1;
		}		
		*((BOOL*)mData) = b;
	}

	/*
	====================
	setBoolArray
	====================
	*/
	INLINE VOID Constant::setBoolArray( const BOOL* pb, U32 count )
	{
		CHECK(pb);
		if( mType == CT_NONE ) mType = CT_BOOL;
		CHECK( mType == CT_BOOL );
		if(mCount != count)
		{
			if(mData){ MDELETE([]mData), mData = NULL; }
			mData = MNEW(U8[count*sizeof(BOOL)]); CHECK(mData);
			mCount = count;
		}
		::memcpy(mData,pb,count*sizeof(BOOL));
	}

	/*
	====================
	setInt
	====================
	*/
	INLINE VOID Constant::setInt( I32 n )
	{
		if( mType == CT_NONE ) mType = CT_INT;
		CHECK( mType == CT_INT );
		if(mCount != 1)
		{
			if(mData){ MDELETE([]mData), mData = NULL; }
			mData = MNEW(U8[sizeof(I32)]); CHECK(mData);
			mCount = 1;
		}		
		*((I32*)mData) = n;
	}

	/*
	====================
	setIntArray
	====================
	*/
	INLINE VOID Constant::setIntArray( const I32* pn, U32 count )
	{
		CHECK(pn);
		if( mType == CT_NONE ) mType = CT_INT_ARRAY;
		CHECK( mType == CT_INT_ARRAY );
		if(mCount != count)
		{
			if(mData){ MDELETE([]mData), mData = NULL; }
			mData = MNEW(U8[count*sizeof(I32)]); CHECK(mData);
			mCount = count;
		}
		::memcpy(mData,pn,count*sizeof(I32));
	}

	/*
	====================
	setFloat
	====================
	*/
	INLINE VOID Constant::setFloat( F32 f )
	{
		if( mType == CT_NONE ) mType = CT_FLOAT;
		CHECK( mType == CT_FLOAT );
		if(mCount != 1)
		{
			if(mData){ MDELETE([]mData), mData = NULL; }
			mData = MNEW(U8[sizeof(F32)]); CHECK(mData);
			mCount = 1;
		}
		*((F32*)mData) = f;
	}

	/*
	====================
	setFloatArray
	====================
	*/
	INLINE VOID Constant::setFloatArray( const F32* pf, U32 count )
	{
		CHECK(pf);
		if( mType == CT_NONE ) mType = CT_FLOAT_ARRAY;
		CHECK( mType == CT_FLOAT_ARRAY );
		if(mCount != count)
		{
			if(mData){ MDELETE([]mData), mData = NULL; }
			mData = MNEW(U8[count*sizeof(F32)]); CHECK(mData);
			mCount = count;
		}
		::memcpy(mData,pf,count*sizeof(F32));
	}

	/*
	====================
	setVector
	====================
	*/
	INLINE VOID Constant::setVector( const Vector4& vec )
	{
		if( mType == CT_NONE ) mType = CT_VECTOR;
		CHECK( mType == CT_VECTOR );
		if(mCount != 1)
		{
			if(mData){ MDELETE([]mData), mData = NULL; }
			mData = MNEW(U8[sizeof(Vector4)]); CHECK(mData);
			mCount = 1;
		}
		*((Vector4*)mData) = vec;
	}

	/*
	====================
	setVectorArray
	====================
	*/
	INLINE VOID Constant::setVectorArray( const Vector4* pvec, U32 count )
	{
		CHECK(pvec);
		if( mType == CT_NONE ) mType = CT_VECTOR_ARRAY;
		CHECK( mType == CT_VECTOR_ARRAY );
		if(mCount != count)
		{
			if(mData){ MDELETE([]mData), mData = NULL; }
			mData = MNEW(U8[count*sizeof(Vector4)]); CHECK(mData);
			mCount = count;
		}
		::memcpy(mData,pvec,count*sizeof(Vector4));
	}

	/*
	====================
	setMatrix
	====================
	*/
	INLINE VOID Constant::setMatrix( const Matrix& mat )
	{
		if( mType == CT_NONE ) mType = CT_MATRIX;
		CHECK( mType == CT_MATRIX );
		if(mCount != 1)
		{
			if(mData){ MDELETE([]mData), mData = NULL; }
			mData = MNEW(U8[sizeof(Matrix)]); CHECK(mData);
			mCount = 1;
		}
		*((Matrix*)mData) = mat;
	}

	/*
	====================
	setMatrixArray
	====================
	*/
	INLINE VOID Constant::setMatrixArray( const Matrix* pmat, U32 count )
	{
		CHECK(pmat);
		if( mType == CT_NONE ) mType = CT_MATRIX_ARRAY;
		CHECK( mType == CT_MATRIX_ARRAY );
		if(mCount != count)
		{
			if(mData){ MDELETE([]mData), mData = NULL; }
			mData = MNEW(U8[count*sizeof(Matrix)]); CHECK(mData);
			mCount = count;
		}
		::memcpy(mData,pmat,count*sizeof(Matrix));
	}

	/*
	====================
	setString
	====================
	*/
	INLINE VOID Constant::setString( const CHAR* string )
	{
		CHECK(string);
		if( mType == CT_NONE ) mType = CT_STRING;
		CHECK( mType == CT_STRING );
		I32 len = ::strlen(string);
		if(mCount != len)
		{
			if(mData){ MDELETE([]mData), mData = NULL; }
			mData = MNEW(U8[(len+1)*sizeof(CHAR)]); CHECK(mData);
			mCount = len;
		}
		::strncpy((CHAR*)mData,string,mCount);
	}

	/*
	====================
	setTexture
	====================
	*/
	INLINE VOID Constant::setTexture( const Texture* texture )
	{
		CHECK(texture);
		if( mType == CT_NONE ) mType = CT_TEXTURE;
		CHECK( mType == CT_TEXTURE );
		mTexturePtr = (Texture*)texture;
	}

//////////////////////////////////////////////////////////////////////////

NAMESPACE_END

//////////////////////////////////////////////////////////////////////////
